home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / file-tra / rdist-6.1 / rdist-6 / rdist-6.1.0-linuxpl2 / src / rshrcmd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-26  |  2.5 KB  |  107 lines

  1.  
  2. /*
  3.  * This is an rcmd() replacement originally by 
  4.  * Chris Siebenmann <cks@utcc.utoronto.ca>.
  5.  */
  6.  
  7. #ifndef lint
  8. static char RCSid[] = 
  9. "$Id: rshrcmd.c,v 1.6 1994/04/26 16:53:42 mcooper Exp $";
  10. #endif
  11.  
  12. #include    "defs.h"
  13.  
  14. #if    !defined(DIRECT_RCMD)
  15.  
  16. #include      <sys/types.h>
  17. #include      <sys/socket.h>
  18. #include      <sys/wait.h>
  19. #include      <signal.h>
  20. #include      <errno.h>
  21. #include      <netdb.h>
  22. #include      <stdio.h>
  23.  
  24. /*
  25.  * This is a replacement rcmd() function that uses the rsh(1c)
  26.  * program in place of a direct rcmd() function call so as to
  27.  * avoid having to be root.
  28.  */
  29. rshrcmd(ahost, port, luser, ruser, cmd, fd2p)
  30.     char      **ahost;
  31.     u_short    port;
  32.     char    *luser, *ruser, *cmd;
  33.     int    *fd2p;
  34. {
  35.     int             cpid;
  36.     struct hostent  *hp;
  37.     int             sp[2];
  38.  
  39.     /* insure that we are indeed being used as we thought. */
  40.     if (fd2p != 0)
  41.         return -1;
  42.     /* validate remote hostname. */
  43.     hp = gethostbyname(*ahost);
  44.     if (hp == 0) {
  45.         error("%s: unknown host", *ahost);
  46.         return -1;
  47.     }
  48.     /* *ahost = hp->h_name; /* This makes me nervous. */
  49.  
  50.     /* get a socketpair we'll use for stdin and stdout. */
  51.     if (getsocketpair(AF_UNIX, SOCK_STREAM, 0, sp) < 0) {
  52.         error("socketpair(AF_UNIX, SOCK_STREAM, 0) failed: %s.", 
  53.               SYSERR);
  54.         return -1;
  55.     }
  56.  
  57.     cpid = fork();
  58.     if (cpid < 0) {
  59.         error("fork failed: %s.", SYSERR);
  60.         return -1;      /* error. */
  61.     }
  62.     if (cpid == 0) {
  63.         /* child. we use sp[1] to be stdin/stdout, and close
  64.            sp[0]. */
  65.         (void) close(sp[0]);
  66.         if (dup2(sp[1], 0) < 0 || dup2(0,1) < 0 || dup2(0, 2) < 0) {
  67.             error("dup2 failed: %s.", SYSERR);
  68.             _exit(255);
  69.         }
  70.         /* fork again to lose parent. */
  71.         cpid = fork();
  72.         if (cpid < 0) {
  73.             error("fork to lose parent failed: %s.", SYSERR);
  74.             _exit(255);
  75.         }
  76.         if (cpid > 0)
  77.             _exit(0);
  78.         /* in grandchild here. */
  79.  
  80.         /*
  81.          * If we are rdist'ing to "localhost" as the same user
  82.          * as we are, then avoid running remote shell for efficiency.
  83.          */
  84.         if (strcmp(*ahost, "localhost") == 0 &&
  85.             strcmp(luser, ruser) == 0) {
  86.             execlp(_PATH_BSHELL, basename(_PATH_BSHELL), "-c",
  87.                    cmd, (char *) NULL);
  88.             error("execlp %s failed: %s.", _PATH_BSHELL, SYSERR);
  89.         } else {
  90.             execlp(path_remsh, basename(path_remsh), 
  91.                    *ahost, "-l", ruser, cmd, (char *) NULL);
  92.             error("execlp %s failed: %s.", path_remsh, SYSERR);
  93.         }
  94.         _exit(255);
  95.     }
  96.     if (cpid > 0) {
  97.         /* parent. close sp[1], return sp[0]. */
  98.         (void) close(sp[1]);
  99.         /* reap child. */
  100.         (void) wait(0);
  101.         return sp[0];
  102.     }
  103.     /*NOTREACHED*/
  104. }
  105.  
  106. #endif    /* !DIRECT_RCMD */
  107.